-
Notifications
You must be signed in to change notification settings - Fork 90
/
AdjacentValuesInterpolator{T}.cs
57 lines (50 loc) · 3.04 KB
/
AdjacentValuesInterpolator{T}.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license.
namespace Microsoft.Psi.Common.Interpolators
{
using System;
using System.Collections.Generic;
/// <summary>
/// Implements an interpolator based on the values adjacent to the interpolation time, i.e. the
/// nearest values before and after the interpolation time.
/// </summary>
/// <typeparam name="T">The type of the messages and of the result.</typeparam>
/// <remarks>The interpolator results do not depend on the wall-clock time of the messages arriving
/// on the secondary stream, i.e., they are based on originating times of messages. As a result,
/// the interpolator might introduce an extra delay as it might have to wait for enough messages on the
/// secondary stream to prove that the interpolation result is correct, irrespective of any other messages
/// that might arrive later.</remarks>
public class AdjacentValuesInterpolator<T> : ReproducibleInterpolator<T>
{
private readonly AdjacentValuesInterpolator<T, T> interpolator;
/// <summary>
/// Initializes a new instance of the <see cref="AdjacentValuesInterpolator{T}"/> class.
/// </summary>
/// <param name="interpolatorFunc">A function which produces an interpolation result, given the two nearest values
/// and the ratio between them.</param>
/// <param name="orDefault">Indicates whether to output a default value when no result is found.</param>
/// <param name="defaultValue">An optional default value to use.</param>
/// <param name="maxSpan">The maximal timespan between adjacent messages for which interpolation will be run.</param>
/// <param name="name">An optional name for the interpolator (defaults to AdjacentValues).</param>
public AdjacentValuesInterpolator(Func<T, T, double, T> interpolatorFunc, bool orDefault, T defaultValue = default, TimeSpan? maxSpan = null, string name = null)
{
T InterpolateWithEndpointHandling(T t1, T t2, double amount)
{
if (amount < 0 || amount > 1)
{
throw new ArgumentException("Cannot pass interpolation values less than 0 or greater than 1." +
$"{nameof(AdjacentValuesInterpolator<T>)} does not support extrapolation.");
}
return amount == 0 ? t1 :
amount == 1 ? t2 :
interpolatorFunc(t1, t2, amount);
}
this.interpolator = new (InterpolateWithEndpointHandling, orDefault, defaultValue, maxSpan, name);
}
/// <inheritdoc/>
public override InterpolationResult<T> Interpolate(DateTime interpolationTime, IEnumerable<Message<T>> messages, DateTime? closedOriginatingTime)
=> this.interpolator.Interpolate(interpolationTime, messages, closedOriginatingTime);
/// <inheritdoc/>
public override string ToString() => this.interpolator.ToString();
}
}